package lib

import (
	"github.com/fsnotify/fsnotify"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"time"
)
var taskContainer []*Task
var logger *log.Logger
var fsWatch *fsnotify.Watcher

func watchDirs(root Task) {
	filepath.Walk(root.Path,func(path string, info os.FileInfo, err error) error{
		if isDir(path) {
			if len(path)>len(root.Path) {
				name := path[len(root.Path)+1:]
				flag,_ := regexp.MatchString(root.Ignore,name)
				if flag {
					return nil
				}
			}
			logger.Println(path)
			fsWatch.Add(path)
		}
		return nil
	})
}


func monitTask(task []Task,done chan <- bool,eventBus chan <- fsnotify.Event) {
	fw,_ := fsnotify.NewWatcher()
	fsWatch = fw
	for _, v:= range task {
		watchDirs(v)
	}


	go func() {
		for{
			select {
			case e :=<-fsWatch.Events:
				eventBus <- e
			case error := <- fsWatch.Errors:
				log.Fatal(error)
				fsWatch.Close()
				done <- false
			}
		}
	}()
}

func Start (task []Task,done chan <- bool,eventBus chan <- fsnotify.Event) {
	GetLogger()
	go monitTask(task,done,eventBus)
	for _, v := range task {
		go func(v Task) {
			taskContainer = append(taskContainer,&v)
		}(v)
	}
}
func isDir(dirname string) bool  {
	fhandler, err := os.Stat(dirname);
	if(! (err == nil || os.IsExist(err)) ) {
		return false
	}else {
		return fhandler.IsDir()
	}
}
func HanderEvent (eventBus <- chan fsnotify.Event,task []Task) {
	for {
		e := <-eventBus
		for _, v := range taskContainer {

			if strings.HasPrefix(e.Name,v.Path) {
				if e.Op == fsnotify.Create {
					if isDir(e.Name) {
						watchDirs(*v)
					}
				}
				name := e.Name[len(v.Path)+1:]
				flag,_ := regexp.MatchString(v.Ignore,name)
				if !flag {
					logger.Println(e.Name)
					v.LastDoTime = time.Now().Unix()
				}
				break
			}
		}	
	}

}


func TaskLoop () {
	for true {
		curTime := time.Now().Unix()

		for _,task := range taskContainer {
			// log.Println(task)
			if task.LastDoTime != 0 && (curTime - task.LastDoTime) > task.DelayTime{
				execCmd(task.Command)
				task.LastDoTime = 0
			}
		}
		time.Sleep(time.Second*1)
		GetLogger()
	}
}

func GetLogger () {
	filname := time.Now().Format("20060102")+".log"
	f,_ := os.OpenFile(filname,os.O_APPEND|os.O_CREATE|os.O_RDWR,0777)
	logger = log.New(f,"",log.Ldate|log.Ltime|log.Lshortfile)
}

type Task struct {
	Path string `yaml:"path"`
	Command string `yaml:"command"`
	LastDoTime int64
	DelayTime int64 `yaml:"delayTime"`
	Ignore string `yaml:"ignore"`
}


